package com.cn.zy.protocol.service;

import com.cn.zy.protocol.domain.School;
import com.cn.zy.protocol.entity.PClass;
import com.cn.zy.protocol.entity.Person;
import com.cn.zy.protocol.entity.Student;
import com.cn.zy.protocol.entity.Teacher;
import com.google.protobuf.InvalidProtocolBufferException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * 首先在官网上下载合适的的protoc官方工具:http://code.google.com/p/protobuf/downloads/list
 * 加不加环境变量随便,使用命令(我这里是加了环境变量):protoc --java_out=./ ./****.proto文件
 * 其中第一个./是将生成的java文件放在本目录下,其二个则是在找到这个proto文件,
 * 这里还需要编写其proto文件...
 * 给个例子:
 *
 *   syntax = "proto2";
 *
 *  option java_outer_classname="PersonProtoBuf";
 *
 *  message Person{
 * 	optional int32 id = 1;
 * 	optional int32 age = 2;
 * 	optional string name= 3;
 * 	optional  bool is_sex= 4;
 * }
 *  message Class{
 * 	optional int32 grade_num = 1;
 * 	optional int32 class_num = 2;
 * 	optional Person head_teacher = 3;
 * 	repeated Person students = 4;
 * }
 *
 * 第一句确定是语法版本
 * 其二是指定生成的class
 * 还可以指定包名
 * 主体:
 *  message Person{...}
 *  主要实体编写区域
 *  其中:
 *      optional:非必需参数
 *      repeated:可以重复存储一个字段,其中是待顺序的存取
 *      required:必要参数
 *
 *      结构体、类，统一定义为 message，实际上是嵌套类
 *
 *      int32,string,bool 数据格式
 *      1,2,3,4 表示数据元素的唯一编号
 *
 *
 * 还可以定义:
 *  enum xx          //枚举定义
 *     {
 *         XXX = 0;
 *         ...
 *     }
 *
 *  struct SS{           //结构体定义
 *         required int s1;
 *         required int s2;
 *     }
 *
 * 具体需要翻墙查看官网文档: https://developers.google.com/protocol-buffers/docs/javatutorial
 * 接下来就需要:使用java程序进行压缩,模拟解压.
 * @author zhangyi
 * @date 2019/2/25 14:42
 * @version 0.0.1
 */
public class ServiceSchool {


    private PClass pClass = null;

    /**
     * 初始化班级
     */
    @Before
    public void initClass(){
        //设置教师类
        Person teacher = new Teacher(1,30,"王老师",false);

        //设置学生类 一个班级50人
        List<Person> allStudents = new ArrayList<>();
        for(int i = 0; i < 50; i++) {
            Person student = null;
            if(i % 2 == 0) {
                student = new Student(i + 1000, (int) (Math.random() * 20), "学生" + i + "号", true);
            }else{
                student = new Student(i + 1000, (int) (Math.random() * 20), "学生" + i + "号", false);
            }
            allStudents.add(student);
        }
        pClass = new PClass(7,3,teacher,allStudents);
    }

    /**
     * 模拟传输的数据字节数组
     */
    private byte[] pipeByArray = null;

    /**
     * 压缩
     */
    @Test
    public void compression() throws InvalidProtocolBufferException {
//        原数据
        System.out.println("原数据的长度: "+pClass.toString().length());
        //压缩后
        School.Class.Builder pClassCom = setBuilder(pClass);
        School.Class build = pClassCom.build();
        pipeByArray = build.toByteArray();
        System.out.println("压缩后数据长度:"+pipeByArray.length);
    }

    /**
     * 模拟解压
     */
    @After
    public void decompression() throws InvalidProtocolBufferException {
        School.Class.Builder aClass = School.Class.parseFrom(pipeByArray).toBuilder();
////        解压
        int classNum = aClass.getClassNum();
        int gradeNum = aClass.getGradeNum();
        School.Person headTeacher = aClass.getHeadTeacher();
        List<School.Person> studentsList = aClass.getStudentsList();
        System.out.println("教师:"+headTeacher.getId()
                +headTeacher.getName()
                +headTeacher.getAge()
                +headTeacher.getIsSex());
        for(School.Person p : studentsList){
            System.out.println(p.getName()+"-"+p.getId()+"-"+p.getIsSex()+"-"+p.getAge());
        }
    }

    /**
     * 添加数据
     *
     * @param pClass
     * @return
     */
    private School.Class.Builder setBuilder(PClass pClass){
        School.Person.Builder person = School.Person.newBuilder();
        //教师类
        Person headTeacher = pClass.getHeadTeacher();
        //添加教师类
        person.setName(headTeacher.getName());
        person.setAge(headTeacher.getAge());
        person.setIsSex(headTeacher.isSex());
        person.setId(headTeacher.getId());
        //教室类
        School.Class.Builder sClass = School.Class.newBuilder();
        sClass.setGradeNum(pClass.getGradeNum());
        sClass.setClassNum(pClass.getClassNum());
        sClass.setHeadTeacher(person);

        //遍历学生
        for(int i = 0; i < pClass.getStudents().size();i++){
            Person p = pClass.getStudents().get(i);
            person.setName(p.getName());
            person.setAge(p.getAge());
            person.setIsSex(p.isSex());
            person.setId(p.getId());
            sClass.addStudents(i,person);
        }

        return sClass;
    }
}
